﻿using System;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace EnterpriseLibraryExtensions.PolicyInjection.UnityBridge.InterceptionStrategies
{
    /// <summary>
    /// The InterceptorFactory returns the most optimal interceptor for the provided type.
    /// </summary>
    internal class InterceptorFactory : IInterceptorFactory
    {
        /// <summary>
        /// This class is used when specifying the type of interceptor to use when creating
        /// the policy injected instance. This mimics the behavior of how the Policy Injection block
        /// creates interceptors.
        /// </summary>
        private static readonly TransparentProxyInterceptor DefaultInjector = new TransparentProxyInterceptor();

        /// <summary>
        /// Gets the most optimal interceptor for the type provided.
        /// </summary>
        /// <param name="type">The type for which to determine the interceptor..</param>
        /// <returns>The interceptor instance.</returns>
        public IInstanceInterceptor GetInstanceInterceptor(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            return DefaultInjector;
        }

        /// <summary>
        /// Gets the type interceptor.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>
        /// The interceptor instance or null if no suitable interceptor was found for type.
        /// </returns>
        public ITypeInterceptor GetTypeInterceptor(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (type.IsAbstract && !type.IsInterface)
            {
                return new VirtualMethodInterceptor();
            }

            return null;
        }
    }
}
